package com.lw.lwte.autoapi.http;

import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONPath;
import com.lw.lwte.common.helper.AssertHelper;
import com.lw.lwte.common.helper.StringHelper;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;

@Slf4j
public class ApiResponse {
    private HttpResponse response;
    private String body;
    private Map<String, List<String>> headers;

    public ApiResponse(HttpResponse response) {
        this.response = response;
    }

    /**
     * 状态断言
     *
     * @param status http状态码
     * @return
     */
    public ApiResponse assertStatus(int status) {
        int actualCode = response.getStatus();
        AssertHelper.isTrue(status == actualCode, String.format("Status code assert failed, except value = %d, actual value = %d", status, actualCode));

        return this;
    }

    /**
     * Body断言
     *
     * @param content :期望请求返回的body内容
     * @return
     */
    public ApiResponse assertBody(String content) {
        String body = getBody();
        AssertHelper.isTrue(content.equals(body), String.format("Body content assert failed.\nExcept value = %s \nActual value = %s",
                content, body));

        return this;
    }

    /**
     * Body contain断言
     *
     * @param content
     * @return
     */
    public ApiResponse assertBodyContains(String content) {
        String body = getBody();
        AssertHelper.isTrue(body.contains(content), String.format("Body content assert failed. \nExcept contain value = %s \nActual value = %s",
                content, body));

        return this;
    }

    /**
     * Json对象断言
     *
     * @param jsonPath    json路径(如response.data)
     * @param expectValue 期望值
     * @return
     */
    public ApiResponse assertJsonByPath(String jsonPath, String expectValue) {
        String actualValue = jsonByPath(jsonPath);
        AssertHelper.isTrue(expectValue.equals(actualValue), String.format("Json content assert failed. \nExpect value = %s \nActual value = %s",
                expectValue, actualValue));

        return this;
    }

    public String getBody() {
        if (body == null) {
            body = response.body();
        }
        return body;
    }

    public Map<String, List<String>> getHeaders() {
        if (headers == null) {
            headers = response.headers();
        }

        return headers;
    }

    public String jsonByPath(String jsonPath) {
        try {
            Object obj = JSON.parseObject(getBody());
            obj = JSONPath.eval(obj, jsonPath);
            return obj.toString();
        } catch (Exception e) {
            log.error(e.getMessage());
        }

        return StringHelper.EMPTY;
    }

    public int getStatus() {
        return response.getStatus();
    }

    public HttpResponse getResponse() {
        return response;
    }

    public String getResponseInfo() {
        StringBuilder stringBuilder = new StringBuilder();
        //Status code
        stringBuilder.append("StatusCode: ").append(getStatus()).append("\n");

        //Header
        Map<String, List<String>> headers = getHeaders();
        if (headers.size() != 0) {
            stringBuilder.append("Header:\n");
            for (String key : headers.keySet()) {
                stringBuilder.append(String.format("%s: %s\n", key, headers.get(key).get(0)));
            }
        }

        //Body
        stringBuilder.append("Body:\n").append(StringHelper.prettyFormat(getBody()));
        stringBuilder.append("\n");

        return stringBuilder.toString();
    }
}